/*
 * Copyright 2021 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <jni.h>

#include <string>
#include "include/core/SkBlendMode.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkTileMode.h"

namespace jetski {
namespace utils {
// RAII helper for jstring -> cstring conversions
class CString {
public:
    CString(JNIEnv *env, const jstring &jstr)
        : fEnv(env), fJString(jstr), fCString(env->GetStringUTFChars(jstr, nullptr))
    {}

    ~CString()
    {
        fEnv->ReleaseStringUTFChars(fJString, fCString);
    }

    const char *str() const
    {
        return fCString;
    }
    operator const char *() const
    {
        return fCString;
    }

private:
    JNIEnv *fEnv;
    const jstring &fJString;
    const char *fCString;

    CString(CString &&) = delete;
    CString(const CString &) = delete;
    CString &operator = (CString &&) = delete;
    CString &operator = (const CString &) = delete;
};

// RAII helper for jstring -> u16String conversions
class U16String {
public:
    U16String(JNIEnv *env, const jstring &jstr)
        : fEnv(env), fJString(jstr), fU16String(env->GetStringChars(jstr, nullptr))
    {}

    ~U16String()
    {
        fEnv->ReleaseStringChars(fJString, fU16String);
    }

    operator const char16_t *() const
    {
        return reinterpret_cast<const char16_t *>(fU16String);
    }

private:
    JNIEnv *fEnv;
    const jstring &fJString;
    const jchar *fU16String;


    U16String(U16String &&) = delete;
    U16String(const U16String &) = delete;
    U16String &operator = (U16String &&) = delete;
    U16String &operator = (const U16String &) = delete;
};

// RAII helper for float array access
class CFloats {
public:
    CFloats(JNIEnv *env, const jfloatArray &jfloats)
        : fEnv(env), fJFloats(jfloats), fCFloats(env->GetFloatArrayElements(jfloats, nullptr))
    {}

    ~CFloats()
    {
        fEnv->ReleaseFloatArrayElements(fJFloats, fCFloats, 0);
    }

    operator const float *() const
    {
        return fCFloats;
    }

private:
    JNIEnv *fEnv;
    const jfloatArray &fJFloats;
    float *fCFloats;


    CFloats(CFloats &&) = delete;
    CFloats(const CFloats &) = delete;
    CFloats &operator = (CFloats &&) = delete;
    CFloats &operator = (const CFloats &) = delete;
};

SkSamplingOptions SamplingOptions(jint, jfloat, jfloat);
SkTileMode TileMode(jint);
SkBlendMode BlendMode(jint);
} // namespace utils
} // namespace jetski
